package cn.mw.cmdb.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.mw.cmdb.controller.ModelController;
import cn.mw.cmdb.entity.*;
import cn.mw.cmdb.enums.ViewTypeEnum;
import cn.mw.cmdb.exception.UploadFileEmptyException;
import cn.mw.cmdb.exception.UploadFileFormatException;
import cn.mw.cmdb.exception.WarnTitleException;
import cn.mw.cmdb.mongoMapper.InstanceInfoMapper;
import cn.mw.cmdb.mongoMapper.ModelInfoMapper;
import cn.mw.cmdb.param.*;
import cn.mw.cmdb.service.InstanceImportHistoryService;
import cn.mw.cmdb.service.ModelService;
import cn.mw.cmdb.service.ServiceAction;
import cn.mw.cmdb.util.CMDBTool;
import cn.mw.cmdb.util.ExportExcel;
import cn.mw.cmdb.view.InstanceInpuFieldsView;
import cn.mw.cmdb.view.ViewConvertContext;
import cn.mw.cmdb.view.ViewManager;
import cn.mw.components.mongodb.entity.CriteriaOpsType;
import cn.mw.components.mongodb.entity.SearchParam;
import cn.mw.components.mongodb.entity.SubCondition;
import cn.mw.components.mongodb.page.MWPage;
import cn.mw.main.api.common.ZabbixDubboService;
import cn.mw.microMonitorCommon.api.cmdb.TableIdEnum;
import cn.mw.microMonitorCommon.api.common.MwTPServerService;
import cn.mw.microMonitorCommon.api.common.ResponseBase;
import cn.mw.microMonitorCommon.api.user.MwUserApi;
import cn.mw.microMonitorCommon.constant.Constants;
import cn.mw.microMonitorCommon.entity.alertDto.CurrentAlertDto;
import cn.mw.microMonitorCommon.entity.cmdb.*;
import cn.mw.microMonitorCommon.entity.common.FieldConditionDto;
import cn.mw.microMonitorCommon.param.MwModuleFieldParam;
import cn.mw.microMonitorCommon.security.utils.SecurityUtils;
import cn.mw.microMonitorCommon.util.DateUtils;
import cn.mw.microMonitorCommon.util.IDModelType;
import cn.mw.microMonitorCommon.util.ModuleIDManager;
import cn.mw.microMonitorCommon.util.SpringUtils;
import com.google.common.base.Strings;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.SerializationUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.bson.types.ObjectId;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static cn.mw.cmdb.controller.MwProcessCallCMDBController.propertyCatologTypeList;
import static cn.mw.cmdb.controller.MwProcessCallCMDBController.propertyTypeList;
import static cn.mw.cmdb.entity.InputDataAuth.*;
import static cn.mw.cmdb.entity.InstanceInfo.SearchPrefix;
import static cn.mw.cmdb.entity.PropertyType.relationIdKey;
import static cn.mw.cmdb.enums.ModelConfigKeyEnum.systemDevType;
import static cn.mw.cmdb.enums.QueryRoomCabinetType.QueryCabinetByRoom;
import static cn.mw.cmdb.enums.QueryRoomCabinetType.QueryInstanceByRoom;
import static cn.mw.cmdb.param.FunctionModuleEnum.enableAutomate;
import static cn.mw.cmdb.param.FunctionModuleEnum.financeReport;
import static cn.mw.cmdb.param.SystemDevTypeEnum.scBankSystemDev;
import static cn.mw.cmdb.processor.MonitorValue.FunctionModule;
import static cn.mw.cmdb.processor.MonitorValue.modelIdKey;
import static cn.mw.cmdb.processor.TableDataFactory.authNameList;
import static cn.mw.cmdb.service.impl.CreatePdfQrCodeTable.labelPrinting;
import static cn.mw.cmdb.util.ListSortUtil.sortListByTypeOrder;
import static cn.mw.cmdb.util.MwCMDBMongoDBApi.getSearchParamList;
import static cn.mw.cmdb.util.UUIDUtils.getUUIDSixNum;
import static cn.mw.cmdb.util.ValConvertUtil.booleanValueConvert;
import static cn.mw.cmdb.util.ValConvertUtil.intValueConvert;
import static cn.mw.cmdb.view.InstanceListViewConverter.serviceManage;
import static cn.mw.cmdb.view.ViewManager.viewType;
import static cn.mw.cmdb.viewProcessor.ModelViewCabinetProcess.cabinetCode;
import static cn.mw.cmdb.viewProcessor.ModelViewRoomProcess.roomCode;
import static cn.mw.cmdb.viewProcessor.ModelViewUNumProcess.relationCabinet;
import static cn.mw.components.mongodb.entity.MongoPropertyType.strValueConvert;
import static cn.mw.microMonitorCommon.util.ListMapObjUtils.objectsToMaps;

/*
 * 资产视图Server
 */
@Slf4j
public class InstanceViewImpl extends ModelBaseServiceImpl<InstanceInfo, Object> {
    private final String formateDate = "yyyy-MM-dd";
    public static final String ID = "instanceView";
    public String systemDevConfigKey = "system.dev.configName";

    public final String ZGBankConfigKey = "ZGBank";
    private String filePathStr = "file.url";
    static final String FILE_MODULE = "file-upload";
    public static final String userNameKey = "负责人名称";
    public static final String orgNameKey = "机构名称";
    public static final String groupNameKey = "用户组名称";

    public static final String userKey = "负责人";
    public static final String orgKey = "机构/部门";
    public static final String groupKey = "用户组";

    //管理部门
    public static final String mwAdminManageOrgKey = "mw_administration_department";
    //管理人
    public static final String mwManagerKey = "mw_manager";


    //资产编码
    public static final String mwAssetCodingKey = "mw_asset_coding";
    public static final String financePageKey = "financePage";

    public static final String mwOriginalValue = "mw_original_value";
    //资产名称
    public static final String mwInstanceNameKey = "mw_instanceName";
    public static final String mwModelGroupNameKey = "modelGroupName";
    public static final String mwModelGroupNameStr = "资产类型";
    public static final String mwModelGroupTableNameStr = "资产类型(*分组层级中最后一级)";
    public static final String mwModelNameKey = "modelName";
    public static final String mwModelNameStr = "资产子类型";
    public static final String mwExcelRowIndex = "mwExcelRowIndex";
    public static final String financeParentId = "financeParentId";
    //品牌
    public static final String mwAssetBrandKey = "mw_assetBrand";
    public static final String qrTextKey = "qrText";
    //型号
    public static final String mwAssetTypeKey = "mw_assetType";
    //采购日期
    public static final String mwPurchaseDateKey = "mw_purchase_date";
    //设备序列号
    public static final String mwProductIdKey = "mw_product_id";
    //开始使用日期
    public static final String mwFacilityUseDateKey = "mw_facilityUseDate";

    //供应商
    public static final String mwSupplierKey = "mw_supplier";
    //资产类别
    public static final String MW_ASSET_TYPE_Key = "mw_asset_type";

    public static final String mw_brand = "mw_brand";
    public static final String mw_hosttemplateid = "mw_hostTemplateId";
    public static final String mw_templateId = "mw_templateId";
    public static final String mw_templateName = "mw_templateName";
    public static final String mw_specification = "mw_specification";
    public static final String mw_monitorMode = "mw_monitorMode";
    public static final String mw_ruleType = "mw_ruleType";
    public static final String mw_port = "mw_port";
    public static final String mw_community = "mw_community";
    public static final String mw_pollingEngine = "mw_pollingEngine";
    public static final String mw_securityLevel = "mw_securityLevel";
    public static final String mw_securityName = "mw_securityName";
    public static final String mw_contextName = "mw_contextName";
    public static final String mw_authAlgName = "mw_authAlgName";
    public static final String mw_authValue = "mw_authValue";
    public static final String mw_privAlgName = "mw_privAlgName";
    public static final String mw_priValue = "mw_priValue";
    public static final String mw_hostName = "mw_hostName";
    public static final String mw_functionModule = "mw_functionModule";
    public static final String mw_monitorFlag = "mw_monitorFlag";


    //首次免费维保期
    public static final String mwFirstFreeMaintenancePeriodKey = "mw_first_free_maintenance_period";

    public static final String relationPropertyIdSuffix = "relationPropertyId";

    public static final String relationIdSuffix = "relationId";
    public static final String relationNameSuffix = "relationName";
    public static final List<String> ignorePropertyIdList = Arrays.asList(mwAssetCodingKey);
    public static final List<String> ignorePropertyIdSCBank = Arrays.asList(OrgKey, GroupKey, UserKey,OrgNameKey,UserNameKey);

    public static final String nameKey = "name";
    public static final String idKey = "id";
    public static final String labelKey = "label";
    public static final String typeKey = "type";
    public static final String structDataKey = "structData";
    public static final String selectDataKey = "selectData";
    public static final String linkDataKey = "linkData";

    private MwUserApi mwUserApi;
    /**
     * 每隔200条存储数据库，然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = 200;
    // 总行数
    private static int totalRows = 0;
    // 总条数
    private static int totalCells = 0;
    private final int ERRORNUM = 20;

    private Set<String> resetPrefixFields;

    private InstanceInfoMapper instanceInfoMapper;

    private ModelInfoMapper modelInfoMapper;

    private CmdbServiceManage cmdbServiceManage;

    private MwTPServerService mwTPServerService;

    private ZabbixDubboService zabbixDubboService;

    private InstanceImportHistoryService instanceImportHistoryService;

    private MessageSource messageSource;

    private ModuleIDManager moduleIDManager;

    private GridFsTemplate gridFsTemplate;

    public InstanceViewImpl(InstanceInfoMapper instanceInfoMapper, CmdbServiceManage cmdbServiceManage
            , ModelInfoMapper modelInfoMapper, MwTPServerService mwTPServerService, ZabbixDubboService zabbixDubboService
            , MwUserApi mwUserApi, InstanceImportHistoryService instanceImportHistoryService, MessageSource messageSource, ModuleIDManager moduleIDManager, GridFsTemplate gridFsTemplate) {
        this.instanceInfoMapper = instanceInfoMapper;
        this.cmdbServiceManage = cmdbServiceManage;
        this.modelInfoMapper = modelInfoMapper;
        this.mwTPServerService = mwTPServerService;
        this.zabbixDubboService = zabbixDubboService;
        this.mwUserApi = mwUserApi;
        this.instanceImportHistoryService = instanceImportHistoryService;
        this.messageSource = messageSource;
        this.moduleIDManager = moduleIDManager;
        this.gridFsTemplate = gridFsTemplate;
    }

    @Override
    public InstanceInfo genObject() {
        return new InstanceInfo();
    }


    @Override
    Object doAdd(InstanceInfo param) throws Exception {
        return null;
    }

    @Override
    boolean doUpdate(InstanceInfo param) throws Exception {
        return false;
    }

    @Override
    boolean doRemove(InstanceInfo param) throws Exception {
        return false;
    }

    @Override
    Object doBatchAdd(Object params) throws Exception {
        return false;
    }

    @Override
    boolean doBatchUpdate(Object params) throws Exception {
        return false;
    }

    @Override
    InstanceInfo doSelectById(Object id) throws Exception {
        return null;
    }

    @Override
    List<InstanceInfo> doSelectList(Object param) throws Exception {
        return null;
    }

    @Override
    boolean doBatchRemove(Object params) throws Exception {
        return false;
    }

    public ModelExportPropertyParam getFieldByFile(MultipartFile file, ModelExportDataInfoParam param) throws Exception {
        ModelExportDataInfoListParam params = new ModelExportDataInfoListParam();
        if (CollectionUtils.isNotEmpty(param.getModelIds())) {
            params.setModelIds(param.getModelIds());
        } else {
            params.setModelId(param.getModelId());
        }
        //获取表头数据list
        ModelExportPropertyParam exportProperty = (ModelExportPropertyParam) getExcelInfo(file, true, params, null);
        //根据modelId获取模型属性名称
        CustomModelServiceImpl modelService = (CustomModelServiceImpl) cmdbServiceManage.getModelService(CustomModelServiceImpl.ID);
        List<ModelInfo> modelInfos = modelService.findByIds(param.getModelIds());
        List<PropertyInfo> propertyInfos = new ArrayList<>();
        for (ModelInfo modelInfo : modelInfos) {
            for (PropertyInfo propertyInfo : modelInfo.getPropertyInfoList()) {
                for (Map<String, Object> map : exportProperty.getListMap()) {
                    String label = strValueConvert(map.get(labelKey));
                    if (propertyInfo.getName().equals(label)) {
                        map.put(idKey, propertyInfo.getId());
                    }
                }
                propertyInfos.add(propertyInfo);
            }
        }
        if (!Strings.isNullOrEmpty(param.getFinanceParentId())) {
            // 查询模型所有父模型
            CustomModelServiceImpl service = (CustomModelServiceImpl) cmdbServiceManage.getModelService(CustomModelServiceImpl.ID);
            ModelSearchParam modelSearchParam = new ModelSearchParam();
            modelSearchParam.addSubCondition(CMDBTool.getFieldName(ModelInfo::getFunctionModule), new SubCondition(CriteriaOpsType.in.name(), FunctionModuleEnum.financeReport.getCode()));
            List<ModelInfo> financeParentModelInfos = service.getAllModelByParentGroup(modelSearchParam);
            Map<String, ModelInfo> modelId2FinanceParentModelInfoMap = financeParentModelInfos.stream().collect(Collectors.toMap(ModelInfo::getId, item -> item, (o1, o2) -> o1));
            List<String> financeParentModelIds = financeParentModelInfos.stream().map(ModelInfo::getId).toList();
            InstanceServiceImpl instanceService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
            instanceService.filterFinanceParentModelProperty(propertyInfos, modelId2FinanceParentModelInfoMap.get(param.getFinanceParentId()), financeParentModelIds);
        }
        Set<String> collect = propertyInfos.stream().map(s -> s.getId()).collect(Collectors.toSet());
        //添加批量导入额外信息:资产分组名称，资产模型名称
        PropertyInfo propertyInfo = new PropertyInfo();
        propertyInfo.setId(mwModelGroupNameKey);
        propertyInfo.setName(mwModelGroupNameStr);
        propertyInfo.setPropertyTypeRef(new PropertyTypeRef(PropertyTypeString.ID));
        if (!collect.contains(mwModelGroupNameKey)) {
            propertyInfos.add(propertyInfo);
        }
        propertyInfo = new PropertyInfo();
        propertyInfo.setId(mwModelNameKey);
        propertyInfo.setName(mwModelNameStr);
        propertyInfo.setPropertyTypeRef(new PropertyTypeRef(PropertyTypeString.ID));
        if (!collect.contains(mwModelNameKey)) {
            propertyInfos.add(propertyInfo);
        }
        exportProperty.setPropertiesInfo(propertyInfos);
        return exportProperty;
    }


    /**
     * 获取导到的数据
     *
     * @param file
     * @param param
     * @throws Exception
     */
    public MwImportResultParam getImportDataInfo(MultipartFile file, ModelExportDataInfoListParam param, List<InstanceImportResultInfo> instanceImportResultInfoList) throws Exception {
        //获取导入list数据
        if (CollectionUtils.isNotEmpty(param.getParamList()) && param.getParamList().size() > 1 && StringUtils.equals(param.getParamList().get(0).getTableName(), "失败原因")) {
            // 前端取第一条数据当匹配key，当excel第一列为失败原因时，会导致匹配数据失败，待前端修改后该逻辑可去除
            param.getParamList().get(0).setIsMatchKey(false);
            param.getParamList().get(1).setIsMatchKey(true);
        }
        MwImportResultParam excelInfo = (MwImportResultParam) getExcelInfo(file, false, param, instanceImportResultInfoList);
        return excelInfo;
    }

    /**
     * 数据导入
     *
     * @param file
     * @param param
     * @throws Exception
     */
    public InstanceImportHistoryInfo importInsertDataInfo(MultipartFile file, ModelExportDataInfoListParam param) throws Exception {
        String systemDevConfig = SpringUtils.getPropertiesValue(systemDevConfigKey);
        String nickName = SecurityUtils.getUser().getNickName();
        InstanceImportHistoryInfo instanceImportHistoryInfo = new InstanceImportHistoryInfo();
        instanceImportHistoryInfo.setId(moduleIDManager.getIDStr(IDModelType.Model));
        instanceImportHistoryInfo.setName(messageSource.getMessage("cmdb_instance_import_task_name", new Object[]{nickName}, LocaleContextHolder.getLocale()));
        instanceImportHistoryInfo.setOperateDate(DateUtils.now());
        instanceImportHistoryInfo.setOperateType(param.getIsImportEditor() != null && param.getIsImportEditor() ?
                Constants.OperationType.IMPORT_UPDATE : Constants.OperationType.IMPORT_ADD);
        instanceImportHistoryInfo.setOperator(nickName);
        instanceImportHistoryInfo.setOperatorId(SecurityUtils.getUser().getId());
        instanceImportHistoryInfo.setFileId(saveFileToGridFS(file));

        List<InstanceImportResultInfo> instanceImportResultInfoList = new ArrayList<>();
        MwImportResultParam importData = getImportDataInfo(file, param, instanceImportResultInfoList);
        List<InstanceInfo> instanceInfoList = new ArrayList<>();
        if (importData != null) {
            BatchAddAndUpdInstanceParam batchAddAndUpdInstanceParam = new BatchAddAndUpdInstanceParam();
            try {
                List dataList = importData.getDataList();
                InstanceImportResultInfo instanceImportResultInfo;
                if (CollectionUtils.isNotEmpty(dataList)) {
                    instanceInfoList = dataList;
                    //是否导入修改
                    if (param.getIsImportEditor() != null && param.getIsImportEditor()) {
                        InstanceServiceImpl instanceService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
                        batchAddAndUpdInstanceParam.setSuccessList(instanceInfoList.stream().map(SerializationUtils::clone).toList());
                        batchAddAndUpdInstanceParam.setPartiallyFlag(true);
                        instanceService.importDataBatchUpdate(instanceInfoList, param, batchAddAndUpdInstanceParam);
                    } else {
                        List<Map> listMap = objectsToMaps(dataList);
                        //金融元页面导入
                        if (!Strings.isNullOrEmpty(param.getFromType()) && financePageKey.equals(param.getFromType())) {
                            if (CollectionUtils.isNotEmpty(listMap)) {
                                for (Map ms : listMap) {
                                    ms.put(FunctionModule, Arrays.asList(financeReport.getCode()));
                                }
                            }
                        }
                        //自贡银行环境导入
                        if (systemDevConfig != null && ZGBankConfigKey.equals(systemDevConfig)) {
                            if (CollectionUtils.isNotEmpty(listMap)) {
                                for (Map ms : listMap) {
                                    ms.put(FunctionModule, Arrays.asList(enableAutomate.getCode()));
                                }
                            }
                        }
                        batchAddAndUpdInstanceParam.setParams(listMap);
                        batchAddAndUpdInstanceParam.setPartiallyFlag(true);
                        cmdbServiceManage.service(batchAddAndUpdInstanceParam, ServiceAction.batchAdd);
                    }
                }
                if (batchAddAndUpdInstanceParam.getSuccessList() != null) {
                    for (InstanceInfo instanceInfo : batchAddAndUpdInstanceParam.getSuccessList()) {
                        // 校验失败的数据写入历史表中
                        instanceImportResultInfo = new InstanceImportResultInfo();
                        instanceImportResultInfo.setInstanceName(instanceInfo.getData().getOrDefault(mwInstanceNameKey, "").toString());
                        instanceImportResultInfo.setInstanceId(strValueConvert(instanceInfo.getId()));
                        instanceImportResultInfo.setModelId(strValueConvert(instanceInfo.getModelId()));
                        instanceImportResultInfo.setFinanceParentModelId(instanceInfo.getFinanceParentId());
                        instanceImportResultInfo.setRowIndex(instanceInfo.getData().getOrDefault(mwExcelRowIndex, "").toString());
                        instanceImportResultInfo.setResult(true);
                        instanceImportResultInfoList.add(instanceImportResultInfo);
                    }
                }
            } catch (Exception e) {
                log.error("importInsertDataInfo error!", e);
                InstanceImportResultInfo instanceImportResultInfo;
                if (CollectionUtils.isEmpty(batchAddAndUpdInstanceParam.getSuccessList()) && CollectionUtils.isNotEmpty(instanceInfoList)) {
                    batchAddAndUpdInstanceParam.setSuccessList(instanceInfoList);
                }
                if (batchAddAndUpdInstanceParam.getSuccessList() != null) {
                    for (InstanceInfo instanceInfo : batchAddAndUpdInstanceParam.getSuccessList()) {
                        // 校验失败的数据写入历史表中
                        instanceImportResultInfo = new InstanceImportResultInfo();
                        instanceImportResultInfo.setInstanceName(instanceInfo.getData().getOrDefault(mwInstanceNameKey, "").toString());
                        instanceImportResultInfo.setInstanceId(strValueConvert(instanceInfo.getId()));
                        instanceImportResultInfo.setModelId(strValueConvert(instanceInfo.getModelId()));
                        instanceImportResultInfo.setFinanceParentModelId(instanceInfo.getFinanceParentId());
                        instanceImportResultInfo.setRowIndex(instanceInfo.getData().getOrDefault(mwExcelRowIndex, "").toString());
                        instanceImportResultInfo.setResult(false);
                        instanceImportResultInfo.setErrorMsg("System Error!");
                        instanceImportResultInfoList.add(instanceImportResultInfo);
                    }
                }
            } finally {
                InstanceImportResultInfo instanceImportResultInfo;
                if (batchAddAndUpdInstanceParam.getCheckFailedList() != null) {

                    List<InstanceCheckVo> checkFailedList = batchAddAndUpdInstanceParam.getCheckFailedList();

                    Map<String, List<InstanceCheckVo>> collect = checkFailedList.stream().collect(Collectors.groupingBy(s -> Strings.isNullOrEmpty(s.getRowIndex()) ? "" : s.getRowIndex()));
                    for (Map.Entry<String, List<InstanceCheckVo>> entry : collect.entrySet()) {
                        String rowIndex = entry.getKey();
                        List<InstanceCheckVo> checkFaileds = entry.getValue();
                        String messageInfo = "";
                        String instanceName = "";
                        String modelId = "";
                        String financeParentModelId = "";
                        for (InstanceCheckVo instanceCheckVo : checkFaileds) {
                            messageInfo += instanceCheckVo.getErrorMessage() + ";";
                            if (Strings.isNullOrEmpty(instanceName)) {
                                instanceName = instanceCheckVo.getInstanceName();
                            }
                            if (Strings.isNullOrEmpty(modelId)) {
                                modelId = instanceCheckVo.getModelId();
                            }
                            if (Strings.isNullOrEmpty(financeParentModelId)) {
                                financeParentModelId = instanceCheckVo.getFinanceParentModelId();
                            }
                        }
                        // 校验失败的数据写入历史表中
                        instanceImportResultInfo = new InstanceImportResultInfo();
                        instanceImportResultInfo.setInstanceName(instanceName);
                        instanceImportResultInfo.setModelId(strValueConvert(modelId));
                        instanceImportResultInfo.setFinanceParentModelId(financeParentModelId);
                        instanceImportResultInfo.setResult(false);
                        instanceImportResultInfo.setRowIndex(rowIndex);
                        instanceImportResultInfo.setErrorMsg(messageInfo);
                        instanceImportResultInfoList.add(instanceImportResultInfo);
                    }
                }
                instanceImportResultInfoList.forEach(item -> {
                    item.setHistoryId(instanceImportHistoryInfo.getId());
                    item.setOperator(nickName);
                    item.setOperateType(instanceImportHistoryInfo.getOperateType());
                    item.setOperateDate(instanceImportHistoryInfo.getOperateDate());
                    item.setRowNo(extractNumber(item.getRowIndex()));
                });
                int successCount = 0;
                int failedCount = 0;
                for (InstanceImportResultInfo item : instanceImportResultInfoList) {
                    if (item.getResult() != null && item.getResult()) {
                        successCount++;
                    } else {
                        failedCount++;
                    }
                }
                instanceImportHistoryInfo.setSuccessCount(successCount);
                instanceImportHistoryInfo.setFailedCount(failedCount);
                if (failedCount > 0) {
                    instanceImportHistoryInfo.setOperateResult(successCount > 0 ? Constants.OperationStatus.PARTIALLY_SUCCESS : Constants.OperationStatus.FAILED);
                } else {
                    instanceImportHistoryInfo.setOperateResult(Constants.OperationStatus.SUCCESS);
                }
                instanceImportHistoryService.saveInstanceImportHistory(instanceImportHistoryInfo);
                instanceImportHistoryService.batchSaveInstanceImportResult(instanceImportResultInfoList);
            }
        }
        return instanceImportHistoryInfo;
    }

    private int extractNumber(String str) {
        if (StringUtils.isEmpty(str)) {
            return 0;
        }
        return Integer.parseInt(str.replaceAll("\\D+", ""));
    }

    private String saveFileToGridFS(MultipartFile file) throws IOException {
        DBObject metaData = new BasicDBObject();
        metaData.put("type", "large_file");
        ObjectId fileId = gridFsTemplate.store(file.getInputStream(), file.getOriginalFilename(), file.getContentType(), metaData);
        return fileId.toString();
    }

    /**
     * 资产导出
     *
     * @param param
     * @param response
     * @throws Exception
     */
    public int exportInstanceList(ExportInstanceParam param, HttpServletResponse response) throws Exception {
        //获取运行环境值
        MwCMDBConfigImpl configServer = (MwCMDBConfigImpl) cmdbServiceManage.getModelService(MwCMDBConfigImpl.ID);
        MwCMDBConfigInfo cmdbConfigInfo = configServer.doSelectByKey(systemDevType.name());
        Object configValue = cmdbConfigInfo.getConfigValue();
        String systemType = "";
        if (configValue instanceof String) {
            systemType = (String) configValue;
        }
        log.info("systemType::" + systemType);

        String nickName = SecurityUtils.getUser().getNickName();
        InstanceImportHistoryInfo instanceImportHistoryInfo = new InstanceImportHistoryInfo();
        instanceImportHistoryInfo.setId(moduleIDManager.getIDStr(IDModelType.Model));
        instanceImportHistoryInfo.setName(messageSource.getMessage("cmdb_instance_export_task_name", new Object[]{nickName}, LocaleContextHolder.getLocale()));
        instanceImportHistoryInfo.setOperateDate(DateUtils.now());
        instanceImportHistoryInfo.setOperateType(Constants.OperationType.EXPORT);
        instanceImportHistoryInfo.setOperator(nickName);
        instanceImportHistoryInfo.setOperatorId(SecurityUtils.getUser().getId());
        instanceImportHistoryInfo.setOperateResult(Constants.OperationStatus.FAILED);
        instanceImportHistoryInfo.setSuccessCount(0);
        instanceImportHistoryInfo.setFailedCount(0);
        List<InstanceImportResultInfo> instanceImportResultInfoList = new ArrayList<>();

        List<Map> labelNameMap = new ArrayList<>();
        List<String> labels = new ArrayList<>();
        List<String> labelNames = new ArrayList<>();
        List<Map> listViewObjectAll = new ArrayList<>();
        List<String> instanceIds = param.getInstanceIds();
        InstanceServiceImpl service = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        List<InstanceInfo> instanceInfoList = service.doListByIdsNotAuth(instanceIds);
        TableHeaderAndDataManage dataManage = SpringUtils.getBean(TableHeaderAndDataManage.class);
        List<String> label = param.getHeader();
        try {
            if (CollectionUtils.isNotEmpty(instanceInfoList)) {
                Map<String, List<String>> collect = instanceInfoList.stream().collect(Collectors.groupingBy(s -> s.getModelId(), Collectors.mapping(InstanceInfo::getId, Collectors.toList())));
                for (Map.Entry<String, List<String>> entry : collect.entrySet()) {
                    String ownModelId = entry.getKey();
                    List<String> ids = entry.getValue();
                    //通用实例字段
                    ExportInstanceParam tableDataParam = new ExportInstanceParam();
                    tableDataParam.setTableId(TableIdEnum.customInstance.getCode());
                    tableDataParam.setEnableMonitorStatus(false);
                    tableDataParam.setShowAllField(true);
                    tableDataParam.setId(ownModelId);
                    tableDataParam.setInstanceIds(ids);
                    tableDataParam.setHeader(param.getHeader());
                    getLabelInfos(dataManage, tableDataParam, listViewObjectAll, systemType, labelNames, labels, labelNameMap);
                }
            } else {
                getLabelInfos(dataManage, param, listViewObjectAll, systemType, labelNames, labels, labelNameMap);
            }
            List<Map> labelNameMapList = new ArrayList<>(labelNameMap);
            List<String> labelsList = new ArrayList<>(labels);

            setGroupNameAndModelNameLabel(labelsList, labelNameMapList);

            List<String> labelsListDis = labelsList.stream().distinct().collect(Collectors.toList());
            List<Map> labelNameMapListDis = labelNameMapList.stream().distinct().collect(Collectors.toList());

            int listNum;
            ExportExcel.exportExcelTest("exportInstanceList", "exportInstanceList", labelNameMapListDis, labelsListDis, listViewObjectAll, "yyyy-MM-dd HH:mm:ss", response, systemType);
            if (CollectionUtils.isEmpty(listViewObjectAll)) {
                listNum = 0;
            } else {
                listNum = listViewObjectAll.size();
            }
            instanceImportHistoryInfo.setSuccessCount(listNum);
            instanceImportHistoryInfo.setOperateResult(listNum > 0 ? Constants.OperationStatus.SUCCESS : Constants.OperationStatus.FAILED);
            InstanceImportResultInfo instanceImportResultInfo;
            for (Map item : listViewObjectAll) {
                instanceImportResultInfo = new InstanceImportResultInfo();
                instanceImportResultInfo.setHistoryId(instanceImportHistoryInfo.getId());
                instanceImportResultInfo.setOperator(nickName);
                instanceImportResultInfo.setResult(true);
                instanceImportResultInfo.setOperateDate(DateUtils.now());
                instanceImportResultInfo.setOperateType(Constants.OperationType.EXPORT);
                instanceImportResultInfo.setFinanceParentModelId((String) item.getOrDefault(financeParentId, ""));
                instanceImportResultInfo.setModelId((String) item.getOrDefault(modelIdKey, ""));
                instanceImportResultInfo.setInstanceName((String) item.getOrDefault(mwInstanceNameKey, ""));
                instanceImportResultInfoList.add(instanceImportResultInfo);
            }
            return listNum;
        } finally {
            instanceImportHistoryService.saveInstanceImportHistory(instanceImportHistoryInfo);
            instanceImportHistoryService.batchSaveInstanceImportResult(instanceImportResultInfoList);
        }
    }


    private void getLabelInfos(TableHeaderAndDataManage dataManage, ExportInstanceParam tableDataParam, List<Map> listViewObjectAll,
                               String systemType, List<String> labelNames, List<String> labels, List<Map> labelNameMap) throws Exception {
        tableDataParam.setPage(new MWPage(1, 9999999));
        List mapList = (List) dataManage.listTableData(tableDataParam);
        List<Map> listViewObject = new ArrayList<>();
        ViewConvertContext context = new ViewConvertContext();
        context.put(serviceManage, cmdbServiceManage);
        context.setType(viewType);
        ViewManager viewManager = SpringUtils.getBean(ViewManager.class);
        Object objList = viewManager.getListViewObject(mapList, InstanceRelationInfo.class, tableDataParam, context);
        if (objList instanceof MWPage) {
            MWPage pageList = (MWPage) objList;
            listViewObject = pageList.getRecords();
        } else {
            listViewObject = (List<Map>) objList;
        }
        listViewObjectAll.addAll(listViewObject);
        List<TableHeaderItem> tableHeaderItems = dataManage.listHeaders(tableDataParam);
        List<String> label = tableDataParam.getHeader();
        if (!CollectionUtils.isEmpty(label)) {
            List<String> finalLabel = label;
            tableHeaderItems = tableHeaderItems.stream().filter(s -> finalLabel.contains(s.getField())).collect(Collectors.toList());
        }

        ModelPropertyServiceImpl propertyService = (ModelPropertyServiceImpl) cmdbServiceManage.getModelService(ModelPropertyServiceImpl.ID);
        List<PropertyInfo> allModelByListShowProperty = propertyService.getAllModelByListShowProperty();
        Map<String, PropertyInfo> disPropertyInfo = allModelByListShowProperty.stream().filter(s -> s.getPropertyTypeRef() != null).collect(Collectors.toMap(s -> s.getId() + "_" + s.getPropertyTypeRef().getTypeId(), s -> s, (
                value1, value2) -> {
            return value2;
        }));


        //四川环境导出数据不展示权限字段
        if (scBankSystemDev.name().equals(systemType)) {
            tableHeaderItems = removerAuthField(tableHeaderItems);
        }
        for (TableHeaderItem headerItem : tableHeaderItems) {
            String fieldId = headerItem.getField();
            String propertyTypeId = headerItem.getPropertyTypeId();
            String key = fieldId + "_" + propertyTypeId;
            String name = headerItem.getHeaderName();
            if (userNameKey.equals(name)) {
                name = userKey;
            }
            if (orgNameKey.equals(name)) {
                name = orgKey;
            }
            if (groupNameKey.equals(name)) {
                name = groupKey;
            }
            if (disPropertyInfo != null && disPropertyInfo.containsKey(key)) {
                PropertyInfo propertyInfo = disPropertyInfo.get(key);
                PropertyType propertyType = PropertyTypeManage.getPropertyType(propertyTypeId);
                Map ms = new HashMap();

                ms.put(nameKey, name);
                boolean flag = propertyType.tableHeaderInfo(ms, propertyInfo, labelNames, labels);
                labelNames.add(name);
                if (flag) {
                    labelNameMap.add(ms);
                }
            }
        }
    }


    /**
     * 下载导入模板
     *
     * @param param
     * @param response
     * @throws Exception
     */
    public void exportModelInstanceTemplate(ExportInstanceTemplate param, HttpServletResponse response) throws Exception {
        List<Map> labelNameMap = new ArrayList<>();
        ModelPropertyServiceImpl propertyService = (ModelPropertyServiceImpl) cmdbServiceManage.getModelService(ModelPropertyServiceImpl.ID);
        List<String> label = new ArrayList<>();
        List<String> labelNames = new ArrayList<>();
        List<Map> mapList = new ArrayList<>();
        Map<String, List<PropertyInfo>> modelAllPropertyMap = propertyService.getModelAllPropertyList(param.getModelIds(), null);
        String financeParentModelId = param.getFinanceParentId();
        //获取运行环境值
        MwCMDBConfigImpl configServer = (MwCMDBConfigImpl) cmdbServiceManage.getModelService(MwCMDBConfigImpl.ID);
        MwCMDBConfigInfo cmdbConfigInfo = configServer.doSelectByKey(systemDevType.name());
        Object configValue = cmdbConfigInfo.getConfigValue();
        String systemType = "";
        if (configValue instanceof String) {
            systemType = (String) configValue;
        }
        log.info("systemType::" + systemType);
        List<String> sortTableHeader = new ArrayList<>();
        //单模型下载模板
        if (!param.getParentModelFlag()) {
            //从对应模型中获取属性类型分组数据
            ModelController bean = SpringUtils.getBean(ModelController.class);
            PropertySearchParam propertySearchParam = new PropertySearchParam();
            propertySearchParam.setModelId(param.getModelIds().get(0));
            propertySearchParam.setInputType(FieldViewAuthType.add.name());
            propertySearchParam.setParentModelId(financeParentModelId);
            ResponseBase responseBase = bean.listInputProperty(propertySearchParam);
            List<InstanceInpuFieldsView> newList = new ArrayList<>();
            if (responseBase != null) {
                Object data = responseBase.getData();
                if (data instanceof List) {
                    List<InstanceInpuFieldsView> dataList = (List<InstanceInpuFieldsView>) data;
                    for (InstanceInpuFieldsView fieldsView : dataList) {
                        List<String> collect = fieldsView.getData().stream().map(s -> s.getId()).collect(Collectors.toList());
                        sortTableHeader.addAll(collect);
                    }
                }
            }
        }

        // 查询模型所有父模型
        CustomModelServiceImpl service = (CustomModelServiceImpl) cmdbServiceManage.getModelService(CustomModelServiceImpl.ID);
        ModelSearchParam modelSearchParam = new ModelSearchParam();
        modelSearchParam.addSubCondition(CMDBTool.getFieldName(ModelInfo::getFunctionModule), new SubCondition(CriteriaOpsType.in.name(), FunctionModuleEnum.financeReport.getCode()));
        List<ModelInfo> financeParentModelInfos = service.getAllModelByParentGroup(modelSearchParam);
        Map<String, ModelInfo> modelId2FinanceParentModelInfoMap = financeParentModelInfos.stream().collect(Collectors.toMap(ModelInfo::getId, item -> item, (o1, o2) -> o1));
        List<String> financeParentModelIds = financeParentModelInfos.stream().map(ModelInfo::getId).toList();

        List<String> fields = new ArrayList<>();
        fields.add(CMDBTool.getFieldName(ModelInfo::getSortNum));
        //获取模型排序信息
        List<ModelInfo> modelInfos = service.getModelInfoByIncludesField(param.getModelIds(), fields);
        //对模型排序
        Collections.sort(modelInfos, (Comparator.comparing(ModelInfo::getSortNum, Comparator.nullsLast(Comparator.naturalOrder()))));

        //先清除缓存数据
        for (ModelInfo modelInfo : modelInfos) {
            String modelId = modelInfo.getId();
            if (modelAllPropertyMap != null && modelAllPropertyMap.containsKey(modelId)) {
                List<PropertyInfo> propertyInfoList = modelAllPropertyMap.get(modelId);
                for (PropertyInfo propertyInfo : propertyInfoList) {
                    PropertyTypeRef propertyTypeRef = propertyInfo.getPropertyTypeRef();
                    PropertyType propertyType = PropertyTypeManage.getPropertyType(propertyTypeRef.getTypeId());
                    propertyType.refresh();
                }
            }
        }
        List<String> ignoreList = new ArrayList<>();
        //四川银行环境，下载模板中忽略机构，负责人
        if (scBankSystemDev.name().equals(systemType)) {
            ignoreList.addAll(ignorePropertyIdSCBank);
            ignoreList.addAll(ignorePropertyIdList);
        }

        for (ModelInfo modelInfo : modelInfos) {
            String modelId = modelInfo.getId();
            if (modelAllPropertyMap != null && modelAllPropertyMap.containsKey(modelId)) {
                List<PropertyInfo> propertyInfoList = modelAllPropertyMap.get(modelId);
                InstanceServiceImpl instanceService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
                instanceService.filterFinanceParentModelProperty(propertyInfoList, modelId2FinanceParentModelInfoMap.get(financeParentModelId), financeParentModelIds);
                if (CollectionUtils.isNotEmpty(sortTableHeader)) {
                    sortListByTypeOrder(propertyInfoList, CMDBTool.getFieldName(PropertyInfo::getId), sortTableHeader);
                } else {
                    propertyService.sortPropertyByListInfo(propertyInfoList, Arrays.asList(modelId));
                }
                for (PropertyInfo propertyInfo : propertyInfoList) {

                    String viewTypeStr = param.getViewType() != null && param.getViewType().equals(ViewTypeEnum.financeView.name()) ? ViewTypeEnum.financeView.name() : ViewTypeEnum.instanceView.name();
                    if(propertyInfo.getFieldViewAuthList()!=null){
                        for (FieldViewAuthVo fieldViewAuthVo : propertyInfo.getFieldViewAuthList()) {
                            if (viewTypeStr.equals(fieldViewAuthVo.getViewType())) {
                                propertyInfo.setFieldViewAuthTypes(fieldViewAuthVo.getFieldViewAuthTypes());
                                break;
                            }
                        }
                    }
                    if (!propertyCatologTypeList.contains(propertyInfo.getPropertyCatologName())
                            && !ignoreList.contains(propertyInfo.getId())
                            && !propertyTypeList.contains(propertyInfo.getPropertyTypeRef().getTypeId())
                            && propertyInfo.getFieldViewAuthTypes() != null &&
                            propertyInfo.getFieldViewAuthTypes().contains(FieldViewAuthType.add)) {
                        String name = "";
                        String info = "(*";
                        if (null != propertyInfo.getFieldAuthTypes()
                                && propertyInfo.getFieldAuthTypes().contains(FieldAuthType.require)) {
                            //必填
                            info += "必填,";
                        }
                        PropertyTypeRef propertyTypeRef = propertyInfo.getPropertyTypeRef();
                        PropertyType propertyType = PropertyTypeManage.getPropertyType(propertyTypeRef.getTypeId());
                        propertyType.init(mwUserApi);
                        Object o = propertyType.tableHeaderTipInfo(propertyTypeRef);

                        info += strValueConvert(o) + ")";
                        if (info.contains(",)")) {
                            info = info.replace(",", "");
                        }
                        if ("(*)".equals(info)) {
                            name = propertyInfo.getName();
                        } else {
                            String lableNameStr = propertyInfo.getName();
                            name = lableNameStr + info;
                        }
                        Map ms = new HashMap();
                        ms.put(nameKey, name);
                        boolean flag = propertyType.tableHeaderInfo(ms, propertyInfo, labelNames, label);
                        labelNames.add(name);
                        if (flag) {
                            labelNameMap.add(ms);
                        }
                    }
                }

            }
        }
        //如果为父模型下载，新增模型分组，模型名称字段
        if (booleanValueConvert(param.getParentModelFlag())) {
            setGroupNameAndModelNameLabel(label, labelNameMap);
        }
        ExportExcel.exportExcelTest("exportInstanceList", "exportInstanceList", labelNameMap, label, mapList, "yyyy-MM-dd HH:mm:ss", response, systemType);
    }

    /**
     * 设置模型分组名称、模型名称字段
     *
     * @param label
     * @param labelNameMap
     */
    private void setGroupNameAndModelNameLabel(List<String> label, List<Map> labelNameMap) {
        Map ms = new HashMap();
        ms.put(nameKey, mwModelGroupTableNameStr);
        if (label.contains(mwModelGroupNameKey)) {
            int index = label.indexOf(mwModelGroupNameKey);
            label.remove(index);
            labelNameMap.remove(index);
        }
        labelNameMap.add(0, ms);
        label.add(0, mwModelGroupNameKey);
        ms = new HashMap();
        ms.put(nameKey, mwModelNameStr);
        if (label.contains(mwModelNameKey)) {
            int index = label.indexOf(mwModelNameKey);
            label.remove(index);
            labelNameMap.remove(index);
        }
        labelNameMap.add(1, ms);
        label.add(1, mwModelNameKey);
    }

    private List<TableHeaderItem> removerAuthField(List<TableHeaderItem> headerItem) {
        List<TableHeaderItem> collect = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(headerItem)) {
            collect = headerItem.stream().filter(s -> !authNameList.contains(s.getField())).collect(Collectors.toList());
        }
        return collect;
    }

    /**
     * 读EXCEL文件，获取信息集合
     *
     * @return
     */
    public Object getExcelInfo(MultipartFile mFile, Boolean isTableHand, ModelExportDataInfoListParam
            param, List<InstanceImportResultInfo> instanceImportResultInfoList) throws
            Exception {
        String fileName = mFile.getOriginalFilename();// 获取文件名
        if (!validateExcel(fileName)) {// 验证文件名是否合格
            throw new UploadFileFormatException();
        }
        boolean isExcel2003 = true;// 根据文件名判断文件是2003版本还是2007版本
        if (isExcel2007(fileName)) {
            isExcel2003 = false;
        }
        Workbook wb = null;
        if (isExcel2003) {// 当excel是2003时,创建excel2003
            wb = new HSSFWorkbook(mFile.getInputStream());
        } else {// 当excel是2007时,创建excel2007
            wb = new XSSFWorkbook(mFile.getInputStream());
        }
        if (isTableHand) {//获取表头数据
            return readExcelHeadInfo(wb, param);// 读取Excel里面表头数据
        } else {
            //获取导入数据按模型
            return readExcelValue(wb, param.getParamList(), param.getIsImportEditor(), instanceImportResultInfoList);// 读取Excel里面数据的信息
        }
    }

    /**
     * 获取表头数据
     *
     * @param wb
     * @return
     */
    private ModelExportPropertyParam readExcelHeadInfo(Workbook wb, ModelExportDataInfoListParam paramInfo) throws
            Exception {
        int num = 1;
        ModelExportPropertyParam param = new ModelExportPropertyParam();
        List<String> filedList = new ArrayList<>();
        List<String> filedList2 = new ArrayList<>();

        // 查询模型所有父模型
        CustomModelServiceImpl service = (CustomModelServiceImpl) cmdbServiceManage.getModelService(CustomModelServiceImpl.ID);
        ModelSearchParam modelSearchParam = new ModelSearchParam();
        modelSearchParam.addSubCondition(CMDBTool.getFieldName(ModelInfo::getFunctionModule), new SubCondition(CriteriaOpsType.in.name(), FunctionModuleEnum.financeReport.getCode()));
        List<ModelInfo> financeParentModelInfos = service.getAllModelByParentGroup(modelSearchParam);
        Map<String, ModelInfo> modelId2FinanceParentModelInfoMap = financeParentModelInfos.stream().collect(Collectors.toMap(ModelInfo::getId, item -> item, (o1, o2) -> o1));
        List<String> financeParentModelIds = financeParentModelInfos.stream().map(ModelInfo::getId).toList();

        ModelPropertyServiceImpl propertyService = (ModelPropertyServiceImpl) cmdbServiceManage.getModelService(ModelPropertyServiceImpl.ID);
        Map<String, List<PropertyInfo>> modelAllPropertyMap = propertyService.getModelAllPropertyList(paramInfo.getModelIds(), null);
        boolean isStructFlag = false;
        Set<String> propertyNames = new HashSet<>();
        for (String modelId : paramInfo.getModelIds()) {
            if (modelAllPropertyMap != null && modelAllPropertyMap.containsKey(modelId)) {
                InstanceServiceImpl instanceService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
                List<PropertyInfo> propertyInfoList = modelAllPropertyMap.get(modelId);
                String financeParentModelId = paramInfo.getFinanceParentId();
                instanceService.filterFinanceParentModelProperty(propertyInfoList, modelId2FinanceParentModelInfoMap.get(financeParentModelId), financeParentModelIds);



                for (PropertyInfo info : propertyInfoList) {

                    String viewTypeStr =  ViewTypeEnum.instanceView.name();
                    if(info.getFieldViewAuthList()!=null){
                        for (FieldViewAuthVo fieldViewAuthVo : info.getFieldViewAuthList()) {
                            if (viewTypeStr.equals(fieldViewAuthVo.getViewType())) {
                                info.setFieldViewAuthTypes(fieldViewAuthVo.getFieldViewAuthTypes());
                                break;
                            }
                        }
                    }

                    if (info.getEnableShow() != null && info.getEnableShow() && info != null && info.getPropertyTypeRef() != null) {
                        propertyNames.add(info.getName());
                        String typeId = info.getPropertyTypeRef().getTypeId();
                        if (PropertyTypeStruct.ID.equals(typeId) && info.getFieldViewAuthTypes().contains(FieldViewAuthType.add)) {
                            isStructFlag = true;
                        }
                    }

                }
            }
        }


        for (int x = 0; x < num; x++) {
            Sheet sheet = wb.getSheetAt(x);
            // 得到Excel的行数
            totalRows = sheet.getPhysicalNumberOfRows();
            if (totalRows > 0 && sheet.getRow(0) != null) {
                Iterator list = sheet.getRow(0).cellIterator();
                int y = 0;
                while (list.hasNext()) {
                    String labelNameStr = list.next().toString();
                    if (labelNameStr.startsWith("^")) {
                        labelNameStr = labelNameStr.substring(1);
                    }
                    //表头字段和属性名称一致，则不需要处理
                    //如果表头字段有（）说明，去除（）的数据
                    if (labelNameStr.indexOf("(*") != -1) {
                        String labelName = labelNameStr.substring(0, labelNameStr.indexOf("(*"));
                        filedList.add(labelName);
                    } else {
                        filedList.add(labelNameStr);
                    }
                }
            }

            if (totalRows > 0 && sheet.getRow(1) != null) {
                Iterator list = sheet.getRow(1).cellIterator();
                while (list.hasNext()) {
                    //如果表头字段有（）说明，去除（）的数据
                    String labelNameStr = list.next().toString();
                    if (labelNameStr.startsWith("^")) {
                        labelNameStr = labelNameStr.substring(1);
                    }
                    if (labelNameStr.indexOf("(*") != -1) {
                        String labelName = labelNameStr.substring(0, labelNameStr.indexOf("(*"));
                        filedList2.add(labelName);
                    } else {
                        filedList2.add(labelNameStr);
                    }
                }
            }

        }
        List<Map<String, Object>> listMap = new ArrayList<>();

        int indexCount = 0;
        List<Map> mList = new ArrayList<>();
        Map<String, List<Map>> mapc = new HashMap();
        for (int x = 0; x < filedList.size(); x++) {
            if (!Strings.isNullOrEmpty(filedList.get(x))) {
                Map mp = new HashMap();
                mp.put("label", filedList.get(x));
                mList = new ArrayList<>();
                if (isStructFlag && !Strings.isNullOrEmpty(filedList2.get(x))) {
                    indexCount = x;
                    Map ms = new HashMap();
                    ms.put("label", filedList2.get(x));
                    mList.add(ms);
                }
                if (isStructFlag) {
                    mp.put("child", mList);

                }
                mapc.put(x + "_" + filedList.get(x), mList);
                listMap.add(mp);
            } else if (filedList2.size() > x && filedList.size() > indexCount) {
                mList = mapc.get(indexCount + "_" + filedList.get(indexCount));
                Map ms = new HashMap();
                ms.put("label", filedList2.get(x));
                mList.add(ms);
            }
        }
        param.setListMap(listMap);
        return param;
    }

    /**
     * 获取导入文件数据
     *
     * @param wb
     * @param list
     * @param isFlag
     * @return
     */
    private Object readExcelValue(Workbook wb, List<ModelExportDataInfoParam> list, Boolean
            isFlag, List<InstanceImportResultInfo> instanceImportResultInfoList) throws Exception {
        //获取运行环境值
        MwCMDBConfigImpl configServer = (MwCMDBConfigImpl) cmdbServiceManage.getModelService(MwCMDBConfigImpl.ID);
        MwCMDBConfigInfo cmdbConfigInfo = configServer.doSelectByKey(systemDevType.name());
        Object configValue = cmdbConfigInfo.getConfigValue();
        String systemType = "";
        if (configValue instanceof String) {
            systemType = (String) configValue;
        }
        log.info("systemType::" + systemType);

        ModelPropertyServiceImpl propertyService = (ModelPropertyServiceImpl) cmdbServiceManage.getModelService(ModelPropertyServiceImpl.ID);
        Map<String, List<PropertyInfo>> modelAllPropertyList = propertyService.getModelAllPropertyList(new ArrayList<>(), null);
        //清除缓存数据
        for (ModelExportDataInfoParam param : list) {
            if (!param.getIgnore()) {
                PropertyType propertyType = PropertyTypeManage.getPropertyType(param.getPropertyType());
                propertyType.refresh();
            }
        }
        boolean isUpdateFlag = isFlag != null && isFlag ? true : false;
        MwImportResultParam resultParam = new MwImportResultParam();
        //单sheet导入
        int num = 1;
        Map map = new HashMap();
        String errorMsg = new String();
        //使用策略模式，针对类型属性分类，生成对应的策略
        int errorNum = 0;
        int listInstanceSize = 0;
        boolean isQuery = true;
        //关联模型实例名称为key，实例Id为value
        Map<String, Integer> relationMap = new HashMap();
        Map<Integer, Object> layOutMapInfo = new HashMap<>();
        Map<String, Map<String, Object>> matchKeyMapInfo = new HashMap<>();
        //导入修改 获取唯一匹配的字段
        String matchKeyProperIndexId = "";
        Set<String> modelIndexSet = new HashSet<>();
        List<String> modelIndexs = new ArrayList<>();
        Integer modelView = 0;
        Map<Integer, Integer> instanceViewMap = new HashMap<>();
        //实例视图类型字段下标
        int viewTypeIndex = -1;
        //刀箱行数字段下标
        int bayRowIndex = -1;
        //刀箱列数字段下标
        int bayColIndex = -1;
        //实例名称字段下标
        int instanceNameIndex = -1;
        List<InstanceInfo> instanceInfoList = new ArrayList<>();
        InstanceImportResultInfo instanceImportResultInfo;
        Map<Integer, String> rowNumByModelIdMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(list)) {
            modelView = list.get(0).getModelView();
            List<String> relationModelIndex = new ArrayList<>();
            List<String> roomAndCabinetrelationModelIndex = new ArrayList<>();
            Boolean isRoomCabinetFlag = false;
            boolean isStructFlag = false;
            //TODO 数据初始化设置，机房机柜关联数据，外部关联字段
            for (ModelExportDataInfoParam exportDataInfoParam : list) {
                //外部关联数据查询
                if ((PropertyTypeExtSingle.ID).equals(exportDataInfoParam.getPropertyType())
                        && !Strings.isNullOrEmpty(exportDataInfoParam.getRelationModelId())) {
                    relationModelIndex.add(exportDataInfoParam.getRelationModelId());
                }

                //判断是否有结构体数据导入
                if (!Strings.isNullOrEmpty(exportDataInfoParam.getStructPropertyId())) {
                    isStructFlag = true;
                }
            }
            //结构体导入，表头占用两行
            int rowNum = isStructFlag ? 2 : 1;
            boolean isParentImport = true;
            String modelId = "";
            String financeParentModelId = "";
            String paramModelId = "";
            for (int x = 0; x < num; x++) {
                Sheet sheet = wb.getSheetAt(x);
                // 得到Excel的行数,有效的行数
                totalRows = getValidRowCount(sheet);
                // 得到Excel的列数(前提是有行数)
                if (totalRows > 1 && sheet.getRow(rowNum - 1) != null) {
                    totalCells = getFilteredColumnCount(sheet.getRow(rowNum - 1));
//                    totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
                }
                Map<String, List> m = new HashMap();
                if (totalRows <= 1) {
                    log.info("导入失败，文件内容为空!");
                    throw new UploadFileEmptyException();
                }

                List<ModelExportDataInfoParam> listAll = new ArrayList<>();
                List<QueryGroupAndModelInfo> queryParams = new ArrayList<>();
                // 先循环获取excel导入的数据
                for (int r = rowNum; r < totalRows; r++) {
                    Row row = sheet.getRow(r);
                    if (row == null) {
                        continue;
                    }
                    List<ModelExportDataInfoParam> dataInfoList = new ArrayList<>();
                    QueryGroupAndModelInfo groupAndModelInfo = new QueryGroupAndModelInfo();
                    for (int c = 0; c < totalCells; c++) {
                        Cell cell = row.getCell(c);
                        ModelExportDataInfoParam param = list.get(c);
                        modelId = param.getModelId();
                        paramModelId = param.getModelId();
                        financeParentModelId = param.getFinanceParentId();

                        if (!Strings.isNullOrEmpty(modelId)) {
                            isParentImport = false;
                        }
                        if (null != cell) {
                            Object cellValue = getCellValue(cell);
                            param.setCellValue(cellValue);
                            ModelExportDataInfoParam copyParam = new ModelExportDataInfoParam();
                            BeanUtil.copyProperties(param, copyParam);
                            copyParam.setRowNum(r);
                            copyParam.setColNum(c);
                            dataInfoList.add(copyParam);
                        }
                        //设备分组名称
                        if (param.getIsMatchKey() != null && param.getIsMatchKey()) {
                            String modelGroupName = strValueConvert(param.getCellValue());
                            groupAndModelInfo.setModelGroupName(modelGroupName);
                        }

                        //设备分组名称
                        if (mwModelGroupNameKey.equals(param.getPropertyId())) {
                            String modelGroupName = strValueConvert(param.getCellValue());
                            groupAndModelInfo.setModelGroupName(modelGroupName);
                        }
                        //设备模型名称
                        if (mwModelNameKey.equals(param.getPropertyId())) {
                            String modelName = strValueConvert(param.getCellValue());
                            groupAndModelInfo.setModelName(modelName);
                        }
                    }
                    queryParams.add(groupAndModelInfo);
                    //获取导入的excel内容数据
                    listAll.addAll(dataInfoList);
                }
                CustomModelServiceImpl service = (CustomModelServiceImpl) cmdbServiceManage.getModelService(CustomModelServiceImpl.ID);
                List<String> allModelPathName = service.getAllModelPathName(paramModelId);
                String modelPath = "";
                if(CollectionUtils.isNotEmpty(allModelPathName)){
                    modelPath = allModelPathName.get(0);
                }


                Map<String, String> mapByGroupNameAndModelName = new HashMap<>();
                Map<String, Map> matchKeyMap = new HashMap<>();

                Map<String, ModelInfo> modelId2FinanceParentModelInfoMap = new HashMap<>();
                List<String> financeParentModelIds = new ArrayList<>();
                if (!Strings.isNullOrEmpty(financeParentModelId)) {
                    // 查询模型所有父模型
                    ModelSearchParam modelSearchParam = new ModelSearchParam();
                    modelSearchParam.addSubCondition(CMDBTool.getFieldName(ModelInfo::getFunctionModule), new SubCondition(CriteriaOpsType.in.name(), FunctionModuleEnum.financeReport.getCode()));
                    List<ModelInfo> financeParentModelInfos = service.getAllModelByParentGroup(modelSearchParam);
                    modelId2FinanceParentModelInfoMap = financeParentModelInfos.stream().collect(Collectors.toMap(ModelInfo::getId, item -> item, (o1, o2) -> o1));
                    financeParentModelIds = financeParentModelInfos.stream().map(ModelInfo::getId).toList();
                }

                if (isParentImport) {
                    List<QueryGroupAndModelInfo> collect = queryParams.stream().distinct().collect(Collectors.toList());
                    CustomModelServiceImpl modelService = (CustomModelServiceImpl) cmdbServiceManage.getModelService(CustomModelServiceImpl.ID);
                    //模型分组名+模型名称对应的模型Id
                    mapByGroupNameAndModelName = modelService.getMapByGroupNameAndModelName(collect);
                }
                //批量修改时，无需指定模型
                InstanceServiceImpl instanceService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
                if (isUpdateFlag) {//唯一匹配校验
                    //唯一匹配
                    matchKeyMap = instanceService.importMatchCheck(listAll, rowNumByModelIdMap, instanceImportResultInfoList);
                }
                // 循环Excel行数
                for (int r = rowNum; r < totalRows; r++) {
                    String checkMessage = "";
                    Row row = sheet.getRow(r);
                    if (row == null) {
                        continue;
                    }
                    boolean isContinue = false;
                    String instanceId = "";
                    InstanceInfo instanceInfo = new InstanceInfo();
                    Map dataMap = new HashMap();
                    String modelGroupName = getCellValueByFieldIndex(list, mwModelGroupNameKey, row);
                    String modelName = getCellValueByFieldIndex(list, mwModelNameKey, row);
                    String mwAssetTypeKey = getCellValueByFieldIndex(list, MW_ASSET_TYPE_Key, row);
                    //四川环境，导入新增
                    if (scBankSystemDev.name().equals(systemType) && !isUpdateFlag) {
                        //对设备类型进行校验
                        if(!Strings.isNullOrEmpty(paramModelId)){
                            //有modelId，表示指定单个模型导入新增
                            if((Strings.isNullOrEmpty(mwAssetTypeKey) || mwAssetTypeKey.indexOf(modelPath) == -1)){
                                checkMessage += "第" + (r + 1) + "行:" + "资产类型匹配不正确";
                                isContinue = true;
                            }
                        }
                        //模型分组，模型名称不为空，表示父模型导入
                        if(!Strings.isNullOrEmpty(modelGroupName) && !Strings.isNullOrEmpty(modelName)){
                            if((Strings.isNullOrEmpty(mwAssetTypeKey) || mwAssetTypeKey.indexOf(modelGroupName + "/" + modelName) == -1)){
                                checkMessage += "第" + (r + 1) + "行:" + "资产类型匹配不正确";
                                isContinue = true;
                            }
                        }
                    }
                    String key = modelGroupName + "_" + modelName;
                    if (mapByGroupNameAndModelName != null && mapByGroupNameAndModelName.containsKey(key)) {
                        //根据表格模型分组，模型名称对应的modelId
                        modelId = mapByGroupNameAndModelName.get(key);
                    }
                    if (isUpdateFlag && rowNumByModelIdMap != null) {
                        //查询匹配的modelId  页面选择的模型id和匹配查询的模型id
                       String queryMatchModelId = rowNumByModelIdMap.get(r);
                        if(scBankSystemDev.name().equals(systemType) && !Strings.isNullOrEmpty(paramModelId) && !paramModelId.equals(queryMatchModelId) ){
                            checkMessage += "第" + (r + 1) + "列:" + "资产类型匹配不正确";
                            isContinue = true;
                        }//表格模型分组，模型名称对应的modelId和匹配查询的模型id
                        if(scBankSystemDev.name().equals(systemType) && !Strings.isNullOrEmpty(modelId) && !modelId.equals(queryMatchModelId) ){
                            checkMessage += "第" + (r + 1) + "列:" + "资产类型匹配不正确";
                            isContinue = true;
                        }
                    }
                    //导入新增，设置instanceId
                    if (!isUpdateFlag) {
                        instanceId = strValueConvert(moduleIDManager.getID(IDModelType.Model));
                    }
                    for (int c = 0; c < totalCells; c++) {
                        Cell cell = row.getCell(c);
                        ModelExportDataInfoParam param = list.get(c);
                        param.setRowNum(r);
                        param.setColNum(c);
                        //是否忽略
                        Boolean ignore = param.getIgnore();
                        //该列数据被忽略
                        if (ignore != null && ignore) {
                            continue;
                        }
                        // 只读数据新增更新不做处理
                        if (param.getIsReadOnly() != null && param.getIsReadOnly()) {
                            continue;
                        }
                        //表头字段名称
                        String name = param.getTableName();
                        //模型属性的Id
                        String propertiesId = param.getPropertyId();
                        //是否唯一
                        Boolean isOnly = param.getIsOnly();
                        //是否必填
                        Boolean isMust = param.getIsMust();
                        //单选、多选下拉值  类型为字符串时，为正则表达式
                        String dropOp = param.getDropOp();
                        Object cellValue = null;
                        //必填校验，
                        if (isMust != null && isMust) {
                            if (null == cell) {
                                if (errorNum < ERRORNUM) {
                                    errorMsg += "第" + (r + 1) + "行第" + (c + 1) + "列:" + name + "不能为空;";
                                    checkMessage += "第" + (c + 1) + "列:" + name + "不能为空;";
                                }
                                errorNum++;
                                isContinue = true;
//                                propertiesList.clear();
                                continue;
                            }
                        }
                        if (null != cell) {
                            //对获取数据类型做判断
                            cellValue = getCellValue(cell);
                            if (isUpdateFlag && booleanValueConvert(param.getIsMatchKey()) && Strings.isNullOrEmpty(strValueConvert(cellValue))) {
                                errorMsg += "第" + (r + 1) + "行第" + (c + 1) + "列," + cellValue + "匹配数据不能为空;";
                                checkMessage += "第" + (c + 1) + "列:" + cellValue + "匹配数据不能为空;";
                                isContinue = true;
                                continue;
                            }
                            //唯一匹配条件校验
                            if (isUpdateFlag && booleanValueConvert(param.getIsMatchKey()) && matchKeyMap != null) {
                                if (matchKeyMap.size() == 0) {
                                    return resultParam;
                                }
                                Map matchKey = matchKeyMap.get(strValueConvert(cellValue));
                                if (matchKey == null) {
                                    errorMsg += "第" + (r + 1) + "行第" + (c + 1) + "列," + cellValue + "匹配数据不存在;";
                                    checkMessage += "第" + (c + 1) + "列:" + cellValue + "匹配数据不存在;";
                                    isContinue = true;
                                    continue;
                                } else {
                                    instanceId = strValueConvert(matchKey.get("id"));
                                }
                            }

                            //模型属性的类型
                            String type = param.getPropertyType();
                            param.setCellValue(cellValue);
                            ImportContextParam contextParam = new ImportContextParam();
                            contextParam.setParam(param);
                            contextParam.setListInfos(listAll);
                            contextParam.setMwUserApi(mwUserApi);
                            if (modelAllPropertyList != null && modelAllPropertyList.get(modelId) != null) {
                                List<PropertyInfo> propertyInfoList = modelAllPropertyList.get(modelId);
                                instanceService.filterFinanceParentModelProperty(propertyInfoList, modelId2FinanceParentModelInfoMap.get(financeParentModelId), financeParentModelIds);
                                contextParam.setModelPropertyList(propertyInfoList);
                            }
                            Object dataInfos = null;
                            if (!Strings.isNullOrEmpty(param.getStructPropertyId())) {
                                PropertyType propertyTypeStruct = new PropertyTypeStruct();
                                dataInfos = propertyTypeStruct.getDataValue(contextParam);
                                propertiesId = param.getStructPropertyId();
                            } else {
                                PropertyType propertyType = PropertyTypeManage.getPropertyType(type);
                                dataInfos = propertyType.getDataValue(contextParam);
                            }
                            MwImportResultParam resultInfo = (MwImportResultParam) dataInfos;
                            if (resultInfo != null) {
                                if (!Strings.isNullOrEmpty(resultInfo.getMessage())) {
                                    errorMsg += "第" + (r + 1) + "行第" + (c + 1) + "列," + resultInfo.getMessage() + ";";
                                    checkMessage += "第" + (c + 1) + "列:" + resultInfo.getMessage() + ";";
                                    isContinue = true;
                                    continue;
                                }
                                if (resultInfo.getCellValue() == null) {
                                    continue;
                                }
                                cellValue = resultInfo.getCellValue();
                                //负责人
                                if (PropertyTypeUser.ID.equals(type) && PropertyTypeUser.ID.equals(propertiesId)) {
                                    instanceInfo.setUsers((List<Long>) cellValue);
                                }
                                //机构
                                else if (PropertyTypeOrg.ID.equals(type) && PropertyTypeOrg.ID.equals(propertiesId)) {
                                    instanceInfo.setOrgs((List<List<Long>>) cellValue);
                                }
                                //用户组
                                else if (PropertyTypeGroup.ID.equals(type) && PropertyTypeGroup.ID.equals(propertiesId)) {
                                    instanceInfo.setGroups((List<Long>) cellValue);
                                } else {
                                    if (cellValue != null) {
                                        //四川银行，管理人映射到负责人，做权限数据
                                        if (scBankSystemDev.name().equals(systemType) && PropertyTypeUser.ID.equals(type) && (mwManagerKey.equals(propertiesId))) {
                                            instanceInfo.setUsers((List<Long>) cellValue);
                                        }
                                        //四川银行，管理部门映射到机构部门，做权限数据
                                        if (scBankSystemDev.name().equals(systemType) && PropertyTypeOrg.ID.equals(type) && (mwAdminManageOrgKey.equals(propertiesId))) {
                                            instanceInfo.setOrgs((List<List<Long>>) cellValue);
                                        }
                                        if (!booleanValueConvert(param.getIsMatchKey())) {
                                            dataMap.put(propertiesId, cellValue);
                                        }
                                    }
                                }
                            }

                        }
                        instanceInfo.setData(dataMap);
                    }
                    if (!Strings.isNullOrEmpty(instanceId)) {
                        instanceInfo.setId(instanceId);
                    }
                    instanceInfo.setModelId(modelId);
                    if (StringUtils.isNotEmpty(financeParentModelId)) {
                        instanceInfo.setFinanceParentId(financeParentModelId);
                        instanceInfo.getData().put(CMDBTool.getFieldName(InstanceInfo::getFunctionModule), Arrays.asList(financeReport.getCode()));
                    }
                    //遇到错误时，跳过该条数据
                    if (!isContinue) {
                        instanceInfo.getData().put(mwExcelRowIndex, "第" + (r + 1) + "行");
                        instanceInfoList.add(instanceInfo);
                    } else if (instanceImportResultInfoList != null) {
                        // 校验失败的数据写入历史表中
                        instanceImportResultInfo = new InstanceImportResultInfo();
                        instanceImportResultInfo.setInstanceName(instanceInfo.getData().getOrDefault(mwInstanceNameKey, "").toString());
                        instanceImportResultInfo.setInstanceId(strValueConvert(instanceInfo.getId()));
                        instanceImportResultInfo.setModelId(modelId);
                        instanceImportResultInfo.setFinanceParentModelId(instanceInfo.getFinanceParentId());
                        instanceImportResultInfo.setResult(false);
                        instanceImportResultInfo.setErrorMsg(checkMessage);
                        instanceImportResultInfo.setRowIndex("第" + (r + 1) + "行");
                        instanceImportResultInfoList.add(instanceImportResultInfo);
                    }
                }
            }
            resultParam.setMessage(errorMsg);
            resultParam.setCountNum(instanceInfoList.size());
            resultParam.setDataList(instanceInfoList);
        }
        log.info("导出错误信息:" + errorMsg + ";导入成功数量:" + resultParam.getCountNum());
        return resultParam;
    }


    public int getFilteredColumnCount(Row row) {

        int lastColumnIndex = row.getLastCellNum(); // 获取总的单元格数
        int nonEmptyCellCount = lastColumnIndex; // 假设所有单元格都不为空

        // 从最后一个单元格向前遍历
        for (int i = lastColumnIndex - 1; i >= 0; i--) {
            Cell cell = row.getCell(i);
            if (cell == null || cell.getCellType() == CellType.BLANK || cell.toString().trim().isEmpty()) {
                nonEmptyCellCount--;
            } else {
                break; // 遇到不为空的单元格则停止
            }
        }
        return nonEmptyCellCount;
    }


    private int getValidRowCount(Sheet sheet) {
        int lastRowNum = sheet.getLastRowNum();
        // 从最后一行开始向上遍历，直到找到非空行
        while (lastRowNum >= 0) {
            Row row = sheet.getRow(lastRowNum);
            if (!isRowEmpty(row)) {
                break;
            }
            lastRowNum--;
        }
        return lastRowNum + 1; // 有效行数是最后一个非空行的索引 + 1
    }

    private boolean isRowEmpty(Row row) {
        if (row == null) {
            return true;
        }
        for (Cell cell : row) {
            if (cell != null && cell.getCellType() != CellType.BLANK) {
                Object cellValue = getCellValue(cell);
                if (cellValue != null && cellValue instanceof String && !strValueConvert(cellValue).trim().isEmpty()) {
                    return false; // 行中有非空单元格
                }
            }
        }
        return true; // 行中所有单元格为空
    }

    /**
     * 验证EXCEL文件
     *
     * @param filePath
     * @return
     */
    public static boolean validateExcel(String filePath) {
        if (filePath == null || !(isExcel2003(filePath) || isExcel2007(filePath))) {
            return false;
        }
        return true;
    }

    // @描述：是否是2003的excel，返回true是2003
    public static boolean isExcel2003(String filePath) {
        return filePath.matches("^.+\\.(?i)(xls)$");
    }

    // @描述：是否是2007的excel，返回true是2007
    public static boolean isExcel2007(String filePath) {
        return filePath.matches("^.+\\.(?i)(xlsx)$");
    }

    /**
     * 判断指定的单元格是否是合并单元格
     *
     * @param sheet
     * @param row    行下标
     * @param column 列下标
     * @return
     */
    private boolean isMergedRegion(Sheet sheet, int row, int column) {
        int sheetMergeCount = sheet.getNumMergedRegions();
        for (int i = 0; i < sheetMergeCount; i++) {
            CellRangeAddress range = sheet.getMergedRegion(i);
            int firstColumn = range.getFirstColumn();
            int lastColumn = range.getLastColumn();
            int firstRow = range.getFirstRow();
            int lastRow = range.getLastRow();
            if (row >= firstRow && row <= lastRow) {
                if (column >= firstColumn && column <= lastColumn) {
                    return true;
                }
            }
        }
        return false;
    }


    private Object getCellValue(Cell cell) {
        Object cellValue = null;
        //对获取数据类型做判断
        switch (cell.getCellType()) {
            case NUMERIC: // 数字
                short format = cell.getCellStyle().getDataFormat();
                if (DateUtil.isCellDateFormatted(cell)) {
                    SimpleDateFormat sdf = null; ////System.out.println("cell.getCellStyle().getDataFormat()="+cell.getCellStyle().getDataFormat());
                    if (format == 20 || format == 32) {
                        sdf = new SimpleDateFormat("HH:mm");
                    } else if (format == 14 || format == 31 || format == 57 || format == 58) { // 处理自定义日期格式：m月d日(通过判断单元格的格式id解决，id的值是58)
                        sdf = new SimpleDateFormat("yyyy-MM-dd");
                        double value = cell.getNumericCellValue();
                        Date date = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(value);
                        cellValue = sdf.format(date);
                    } else {// 日期
                        sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    }
                    try {
                        cellValue = sdf.format(cell.getDateCellValue());// 日期
                    } catch (Exception e) {
                        try {
                            throw new Exception("日期格式错误:".concat(e.toString()));
                        } catch (Exception e1) {
                            e1.printStackTrace();
                        }
                    }
                } else {
                    DataFormatter dataFormatter = new DataFormatter();
                    cellValue = dataFormatter.formatCellValue(cell);
                }
                break;
            case STRING: // 字符串
                //数据类型和选定的模型属性类型必须匹配
                cellValue = cell.getStringCellValue();
                break;
            case BOOLEAN: // Boolean
                cellValue = cell.getBooleanCellValue();
                break;
            case FORMULA: // 公式
                cellValue = cell.getCellFormula();
                break;
            case BLANK: // 空值
                cellValue = "";
                break;
            case ERROR: // 故障
                break;
            default:
                break;
        }
        return cellValue;
    }

    public Object testMethod(MwModuleFieldParam mwModuleFieldParam) {

        return null;
    }

    /**
     * 获取外部关联下拉数据
     *
     * @param relationPropertyInfo
     * @return
     * @throws Exception
     */
    public List<MwRelationInstanceParam> getSelectDataByRelation(PropertyRelationInfo relationPropertyInfo) throws
            Exception {
        String modelId = relationPropertyInfo.getRelationModelId();
        String propertyId = relationPropertyInfo.getRelationPropertyId();
        List<MwRelationInstanceParam> relationInstanceList = new ArrayList<>();
        InstanceServiceImpl service = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        InstanceSearchParam instanceSearchParam = new InstanceSearchParam();
        instanceSearchParam.setModelId(modelId);
        if (!Strings.isNullOrEmpty(relationPropertyInfo.getQueryField())) {
            String queryField = relationPropertyInfo.getQueryField();
            Map s = new HashMap();
            s.put(queryField, relationPropertyInfo.getQueryValue());
            instanceSearchParam.setData(s);
        }
        List<InstanceInfo> instanceInfoList = service.doSelectList(instanceSearchParam);
        for (InstanceInfo instanceInfo : instanceInfoList) {
            MwRelationInstanceParam instanceRelationInfo = new MwRelationInstanceParam();
            if (mwInstanceNameKey.equals(propertyId)) {
                //只有关联字段是实例名称时，此时的实例id才有意义
                instanceRelationInfo.setRelationId(instanceInfo.getId());
            }
            Object value = instanceInfo.getData().get(propertyId);
            instanceRelationInfo.setRelationName(strValueConvert(value));
            instanceRelationInfo.setRelationPropertyId(propertyId);
            if (StringUtils.isNotEmpty(relationPropertyInfo.getLinkPropertyId())) {
                instanceRelationInfo.setLinkPropertyId(relationPropertyInfo.getLinkPropertyId());
                Object linkPropertyValue = instanceInfo.getData().get(relationPropertyInfo.getLinkPropertyId());
                if (linkPropertyValue instanceof Map) {
                    instanceRelationInfo.setLinkPropertyName(strValueConvert(((Map) linkPropertyValue).get(PropertyType.relationNameKey)));
                    instanceRelationInfo.setLinkId(strValueConvert(((Map) linkPropertyValue).get(PropertyType.relationIdKey)));
                } else {
                    instanceRelationInfo.setLinkPropertyName(strValueConvert(linkPropertyValue));
                }
            }
            relationInstanceList.add(instanceRelationInfo);
        }
        return relationInstanceList;
    }

    public void exportTest(Object params) throws Exception {
        InstanceServiceImpl service = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        Object o = service.doBatchUpdateMulti(params);
    }


    public void testRelationSync(Map mapInstance) throws Exception {
        //前端页面修改后的数据
        InstanceInfo afterInstanceInfo = new InstanceInfo();
        ModelService modelService = cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        Object convert = cmdbServiceManage.convert(modelService, (Map) mapInstance);
        //将map参数转为InstanceInfo
        if (convert != null && convert instanceof InstanceInfo) {
            afterInstanceInfo = (InstanceInfo) convert;
        }
        String afterInstanceName = "";
        if (afterInstanceInfo != null) {
            afterInstanceName = afterInstanceInfo.getInstanceName();
        }
        ModelPropertyServiceImpl propertyService = (ModelPropertyServiceImpl) cmdbServiceManage.getModelService(ModelPropertyServiceImpl.ID);
        List<PropertyInfo> allModelPropertyList = propertyService.getAllModelPropertyList();
        //外部关联属性
        Set<String> relationSet = new HashSet<>();
        relationSet.add(PropertyTypeExtSingle.ID);
        relationSet.add(PropertyTypeExtMultiple.ID);
        //获取所有外部关联的属性
        Map<String, PropertyInfo> collect = allModelPropertyList.stream().filter(s -> (s.getPropertyTypeRef() != null && relationSet.contains(s.getPropertyTypeRef().getTypeId()))).collect(Collectors.toMap(s -> s.getId(), s -> s, (o1, o2) -> o1));
        InstanceServiceImpl instanceService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        //TODO 查询数据库中修改前的数据
        InstanceInfo beforeInstanceInfo = instanceService.getInstanceInfoById(afterInstanceInfo.getId());
        String beforeInstanceName = "";
        if (beforeInstanceInfo != null) {
            beforeInstanceName = beforeInstanceInfo.getInstanceName();
        }
        //前后数据实例名称不相同，说明修改过该字段
        if (afterInstanceName != null && !afterInstanceName.equals(beforeInstanceName)) {
            List<Criteria> criteriaList = new ArrayList<>();
            Update update = new Update();

            for (Map.Entry<String, PropertyInfo> entry : collect.entrySet()) {
                String k = entry.getKey();
                PropertyInfo v = entry.getValue();
                String fieldName = k;
                PropertyInfo propertyInfo = v;
                criteriaList.add(Criteria.where(getRelationIdPath(fieldName)).is(beforeInstanceInfo.getId()));
//                criteriaList.add(Criteria.where(getRelationPropertyIdPath(fieldName)).is(relationPropertyId));
                update.set(getRelationNamePath(fieldName, propertyInfo), afterInstanceName);
            }

            Criteria criteria = new Criteria().orOperator(criteriaList);
            instanceInfoMapper.updateMulti(new Query(criteria), update);
        }
    }

    /**
     * 获取excelrow中指定字段的数据
     *
     * @param list
     * @param field
     * @param row
     * @return
     */
    private String getCellValueByFieldIndex(List<ModelExportDataInfoParam> list, String field, Row row) {
        String fieldValue = "";
        //获取指定字段的index位置
        OptionalInt modelGroupOpt = IntStream.range(0, list.size()).filter(s -> field.equals(list.get(s).getPropertyId())).findFirst();
        if (modelGroupOpt.isPresent()) {
            int modelGroupIndex = modelGroupOpt.getAsInt();
            Cell cell = row.getCell(modelGroupIndex);
            if (cell != null) {
                fieldValue = strValueConvert(getCellValue(cell));
            }
        }
        return fieldValue;
    }


    public static String getRelationIdPath(String name) {
        String path = SearchPrefix + "." + name + "." + relationIdSuffix;
        return path;
    }

    public static String getNotPrefixRelationIdPath(String name) {
        String path = name + "." + relationIdSuffix;
        return path;
    }

    private String getRelationPropertyIdPath(String name) {
        String path = SearchPrefix + "." + name + "." + relationPropertyIdSuffix;
        return path;
    }

    private String getRelationNamePath(String name, PropertyInfo propertyInfo) {
        String path = "";
        if (PropertyTypeExtMultiple.ID.equals(propertyInfo.getPropertyTypeRef().getTypeId())) {
            path = SearchPrefix + "." + name + "." + "$[]" + "." + relationNameSuffix;
        } else {
            path = SearchPrefix + "." + name + "." + relationNameSuffix;
        }
        return path;
    }

    public MwProcessCallInstanceInfo getInstanceListAndHeader(MwModuleFieldParam mwModuleFieldParam) throws
            Exception {
        MwProcessCallInstanceInfo processCallInstanceInfo = new MwProcessCallInstanceInfo();
        TableSearchParam tableSearchParam = new TableSearchParam();
        //通用实例字段
        tableSearchParam.setTableId(TableIdEnum.commonInstance.getCode());
        if (CollectionUtils.isNotEmpty(mwModuleFieldParam.getIds())) {
            tableSearchParam.setInstanceIds(mwModuleFieldParam.getIds());
        }
        TableHeaderAndDataManage dataManage = SpringUtils.getBean(TableHeaderAndDataManage.class);
        try {
            List<FieldConditionDto> conditionDtoList = mwModuleFieldParam.getConditionDtoList();
            tableSearchParam.setIgnoreDataAuth(mwModuleFieldParam.isIgnoreDataAuth());
            SearchParam searchParamList = getSearchParamList(conditionDtoList);
            BeanUtil.copyProperties(searchParamList, tableSearchParam, CopyOptions.create().setIgnoreNullValue(true));
            if (intValueConvert(mwModuleFieldParam.getPageSize()) != 0 && intValueConvert(mwModuleFieldParam.getPageNum()) != 0) {
                MWPage mwPage = new MWPage();
                mwPage.setSize(mwModuleFieldParam.getPageSize());
                mwPage.setCurrent(mwModuleFieldParam.getPageNum());
                tableSearchParam.setPage(mwPage);
            }
            List<TableHeaderItem> tableHeaderItems = dataManage.listHeaders(tableSearchParam);
            List<Map> list = (List<Map>) dataManage.listTableData(tableSearchParam);
            processCallInstanceInfo.setInstanceList(list);
            processCallInstanceInfo.setHeaderItems(tableHeaderItems);
        } catch (Exception e) {
            throw new WarnTitleException("process-call-model-err");
        }
        return processCallInstanceInfo;
    }


    public Object getInstanceNumByModel() throws Exception {
        InstanceServiceImpl instanceService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        InstanceSearchParam instanceSearchParam = new InstanceSearchParam();
        List<InstanceInfoExtend> instanceInfoExtends = instanceService.aggregateList(instanceSearchParam);

        Map<String, String> modelInfoMap = instanceInfoExtends.stream().filter(s -> !Strings.isNullOrEmpty(s.getModelName())).collect(Collectors.toMap(s -> s.getModelName(), s -> s.getModelId(), (
                value1, value2) -> {
            return value2;
        }));


        Map<String, Long> collect = instanceInfoExtends.stream().filter(s -> !Strings.isNullOrEmpty(s.getModelName())).collect(Collectors.groupingBy(s -> s.getModelName(), Collectors.counting()));
        Map<String, MwModelInstanceCount> map = new HashMap<>();
        collect.forEach((k, v) -> {
            String modelName = k;
            Long instanceNum = v;
            MwModelInstanceCount instanceCount = new MwModelInstanceCount();
            if (modelInfoMap != null && modelInfoMap.containsKey(modelName)) {
                String modelId = modelInfoMap.get(modelName);
                instanceCount.setModelId(modelId);
            }
            instanceCount.setInstanceNum(instanceNum);
            map.put(modelName, instanceCount);
        });
        return map;
    }

    /**
     * 批量下载二维码标签
     */
    public void batchUploadQrCodeLabel(Object param, HttpServletResponse response) throws Exception {
        TableSearchParam tableDataParamOld = (TableSearchParam) param;
        List<Map> list = new ArrayList<>();

        List<String> instanceIds = tableDataParamOld.getInstanceIds();
        InstanceServiceImpl service = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        List<InstanceInfo> instanceInfoList = service.doListByIdsNotAuth(instanceIds);
        if (CollectionUtils.isNotEmpty(instanceInfoList)) {
            Map<String, List<String>> collect = instanceInfoList.stream().collect(Collectors.groupingBy(s -> s.getModelId(), Collectors.mapping(InstanceInfo::getId, Collectors.toList())));
            for (Map.Entry<String, List<String>> entry : collect.entrySet()) {
                String ownModelId = entry.getKey();
                List<String> ids = entry.getValue();
                //通用实例字段
                TableSearchParam tableDataParam = new TableSearchParam();
                tableDataParam.setTableId(TableIdEnum.customInstance.getCode());
                tableDataParam.setEnableMonitorStatus(false);
                tableDataParam.setShowAllField(true);
                tableDataParam.setId(ownModelId);
                tableDataParam.setInstanceIds(ids);
                tableDataParam.setSortName(tableDataParamOld.getSortName());
                tableDataParam.setSortOrder(tableDataParamOld.getSortOrder());
                TableHeaderAndDataManage dataManage = SpringUtils.getBean(TableHeaderAndDataManage.class);
                List dataList = (List) dataManage.listTableData(tableDataParam);
                List<Map> listViewObject = new ArrayList<>();
                ViewConvertContext context = new ViewConvertContext();
                context.put(serviceManage, cmdbServiceManage);
                context.setType(viewType);
                ViewManager viewManager = SpringUtils.getBean(ViewManager.class);
                tableDataParam.setPage(null);

                Object objList = viewManager.getListViewObject(dataList, InstanceRelationInfo.class, tableDataParam, context);
                if (objList instanceof MWPage) {
                    MWPage pageList = (MWPage) objList;
                    listViewObject = pageList.getRecords();
                } else {
                    listViewObject = (List<Map>) objList;
                }
                Set modelIdSet = new HashSet();
                if (CollectionUtils.isNotEmpty(listViewObject)) {
                    modelIdSet = listViewObject.stream().map(s -> strValueConvert(s.get(modelIdKey))).collect(Collectors.toSet());
                }
                ModelPropertyServiceImpl propertyService = (ModelPropertyServiceImpl) cmdbServiceManage.getModelService(ModelPropertyServiceImpl.ID);
                Map<String, List<PropertyInfo>> modelAllPropertyList = new HashMap<>();
                //获取模型对应的全部属性集合(包含父模型的属性)
                if (CollectionUtils.isNotEmpty(modelIdSet)) {
                    modelAllPropertyList = propertyService.getModelAllPropertyList(new ArrayList<>(modelIdSet), null);
                }


                //根据模型来获取二维码属性，
                if (CollectionUtils.isNotEmpty(listViewObject)) {
                    for (Map mapData : listViewObject) {
                        Map ms = new HashMap();
                        Map<String, Object> data = mapData;
                        String modelId = strValueConvert(mapData.get(modelIdKey));

                        //挂载的金融元父模型id
                        String financePId = strValueConvert(mapData.get(financeParentId));
                        //二维码写入内容
                        String qrText = "";
                        if (modelAllPropertyList != null && modelAllPropertyList.containsKey(modelId)) {
                            List<PropertyInfo> propertyInfoList = modelAllPropertyList.get(modelId);
                            CustomModelServiceImpl modelService = (CustomModelServiceImpl) cmdbServiceManage.getModelService(CustomModelServiceImpl.ID);
                            //如果指定了金融元父模型，过滤其他的金融元父模型
                            List<ModelInfo> financeParentModelInfos = modelService.getFinanceParentModelInfos();
                            Map<String, ModelInfo> modelId2FinanceParentModelInfoMap = financeParentModelInfos.stream().collect(Collectors.toMap(ModelInfo::getId, item -> item, (o1, o2) -> o1));
                            List<String> financeParentModelIds = financeParentModelInfos.stream().map(ModelInfo::getId).toList();
                            service.filterFinanceParentModelProperty(propertyInfoList, modelId2FinanceParentModelInfoMap.get(financePId), financeParentModelIds);
                            //获取属性id->属性名称
                            Map<String, PropertyInfo> propertyById = propertyInfoList.stream().collect(Collectors.toMap(s -> s.getModelId() + "_" + s.getId(), s -> s, (
                                    value1, value2) -> {
                                return value2;
                            }));
                            if (propertyInfoList != null) {
                                List<PropertyInfo> qrCodePropertyList = propertyInfoList.stream().filter(s -> s.getPropertyTypeRef() != null && PropertyTypeQRCode.ID.equals(s.getPropertyTypeRef().getTypeId())).collect(Collectors.toList());
                                if (CollectionUtils.isNotEmpty(qrCodePropertyList)) {
                                    for (PropertyInfo propertyInfo : qrCodePropertyList) {
                                        PropertyType propertyType = propertyInfo.getPropertyType();
                                        if (propertyInfo.getPropertyTypeRef() != null && propertyInfo.getPropertyTypeRef().getContext() != null) {
                                            Object defaultContextValue = propertyType.getDefaultContextValue(propertyInfo.getPropertyTypeRef().getContext());
                                            if (defaultContextValue != null && defaultContextValue instanceof List) {
                                                //获取二维码关联的字段
                                                List fieldList = (List) defaultContextValue;
                                                for (Object objMs : fieldList) {
                                                    Map objMap = (Map) objMs;//获取字段对应的数据值
                                                    String disPropertyId = strValueConvert(objMap.get("id"));
                                                    if (propertyById != null && propertyById.containsKey(disPropertyId)) {
                                                        PropertyInfo disPropertyInfo = propertyById.get(disPropertyId);
                                                        Object val = data.get(disPropertyInfo.getId());
                                                        String name = disPropertyInfo.getName();
                                                        qrText += name + ":" + val + ";\n";
                                                    }
                                                }
                                            }
                                        }
                                        //实物标签号
                                        String mwAssetCoding = strValueConvert(data.get(mwAssetCodingKey));
                                        ms.put(mwAssetCodingKey, mwAssetCoding);
                                        //资产名称
                                        String mwInstanceName = strValueConvert(data.get(mwInstanceNameKey));
                                        ms.put(mwInstanceNameKey, mwInstanceName);

                                        //关联字段未设置，默认使用资产编码或资产名称
                                        if (Strings.isNullOrEmpty(qrText)) {
                                            qrText = Strings.isNullOrEmpty(mwAssetCoding) ? mwInstanceName : mwAssetCoding;
                                        }
                                        ms.put(qrTextKey, qrText);
                                        //品牌
                                        String mwAssetBrand = strValueConvert(data.get(mwAssetBrandKey));
                                        ms.put(mwAssetBrandKey, mwAssetBrand);
                                        //型号
                                        String mwAssetType = strValueConvert(data.get(mwAssetTypeKey));
                                        ms.put(mwAssetTypeKey, mwAssetType);

                                        Object mwCommencementDate = data.get(mwFacilityUseDateKey);
                                        if (mwCommencementDate != null && mwCommencementDate instanceof Date) {
                                            mwCommencementDate = DateUtils.format((Date) mwCommencementDate, formateDate);
                                        }
                                        //开始使用日期
                                        ms.put(mwFacilityUseDateKey, mwCommencementDate);

                                        //序列号
                                        String mwProductId = strValueConvert(data.get(mwProductIdKey));
                                        ms.put(mwProductIdKey, mwProductId);

                                        Object mwPurchaseDate = data.get(mwPurchaseDateKey);
                                        if (mwPurchaseDate != null && mwPurchaseDate instanceof Date) {
                                            mwPurchaseDate = DateUtils.format((Date) mwPurchaseDate, formateDate);
                                        }
                                        //采购日期
                                        ms.put(mwPurchaseDateKey, mwPurchaseDate);

                                        //供应商
                                        String mwSupplier = strValueConvert(data.get(mwSupplierKey));
                                        ms.put(mwSupplierKey, mwSupplier);

                                        //资产类别
                                        String mw_asset_type = strValueConvert(data.get(MW_ASSET_TYPE_Key));
                                        ms.put(MW_ASSET_TYPE_Key, mw_asset_type);

                                        //机构部门
                                        String orgNameStr = strValueConvert(data.get(mwAdminManageOrgKey));
                                        ms.put(OrgNameKey, orgNameStr);
                                        list.add(ms);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        if (CollectionUtils.isNotEmpty(list)) {
            labelPrinting(list, response);
        }
    }

    /**
     * 根据设备信息获取当前告警数据
     *
     * @return
     */
    public List<AlertInstanceInfoParam> getInstanceAlertList(String roomId) throws Exception {
        InstanceServiceImpl service = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        //获取机房信息
        InstanceInfo roomInfo = service.getInstanceInfoById(roomId);
        String roomCodeVal = "";
        String roomName = roomInfo.getInstanceName();
        if (roomInfo != null && roomInfo.getData() != null) {
            roomCodeVal = strValueConvert(roomInfo.getData().get(roomCode));
        }
        //机房Id所有机柜信息
        List<InstanceInfo> cabinetListInfo = service.getInstanceListByRelationIds(Arrays.asList(roomId), QueryCabinetByRoom);
        //机柜id->机柜code Map
        Map<String, InstanceInfo> cabinetInfoByIdMap = cabinetListInfo.stream().filter(s -> s.getData() != null && !Strings.isNullOrEmpty(strValueConvert(s.getData().get(cabinetCode)))).collect(Collectors.toMap(s -> s.getId(), s -> s, (
                value1, value2) -> {
            return value2;
        }));

        //根据机房Id下所有资产实例数据
        List<InstanceInfo> instanceListInfo = service.getInstanceListByRelationIds(Arrays.asList(roomId), QueryInstanceByRoom);
        //数据转换，实例id - 关联机柜Id
        Map<String, String> cabinetIdByInstnaceIdMap = instanceListInfo.stream().filter(s -> s.getData() != null && !Strings.isNullOrEmpty(strValueConvert(((Map) s.getData().get(relationCabinet)).get(relationIdKey)))).collect(Collectors.toMap(s -> s.getId(), s -> strValueConvert(((Map) s.getData().get(relationCabinet)).get(relationIdKey)), (
                value1, value2) -> {
            return value2;
        }));
        List<CurrentAlertDto> alertList = service.getAlertListByInstanceInfos(instanceListInfo, null);
        List<AlertInstanceInfoParam> alertInstanceInfoParams = BeanUtil.copyToList(alertList, AlertInstanceInfoParam.class);
        for (AlertInstanceInfoParam alertInfo : alertInstanceInfoParams) {
            String instanceId = alertInfo.getInstanceId();
            alertInfo.setRoomCode(roomCodeVal);
            alertInfo.setRoomName(roomName);
            if (cabinetIdByInstnaceIdMap != null && cabinetIdByInstnaceIdMap.containsKey(instanceId)) {
                String cabinetId = cabinetIdByInstnaceIdMap.get(instanceId);
                if (cabinetInfoByIdMap != null && cabinetInfoByIdMap.containsKey(cabinetId)) {
                    InstanceInfo cabinetInstanceInfo = cabinetInfoByIdMap.get(cabinetId);
                    String cabinetName = cabinetInstanceInfo.getInstanceName();
                    String cabinetCodeVal = strValueConvert(cabinetInstanceInfo.getData().get(cabinetCode));
                    alertInfo.setCabinetCode(cabinetCodeVal);
                    alertInfo.setCabinetName(cabinetName);
                }
            }
        }
        return alertInstanceInfoParams;
    }

    public List<String> cmdbUploadFile(MultipartFile multipartFile) throws Exception {
        String filePath = SpringUtils.getPropertiesValue(filePathStr);
        String fileNameInTable = "";
        if (multipartFile.isEmpty()) {
            throw new UploadFileEmptyException();
        }
        List<String> fileNames = new ArrayList<>();
        String originalFilename = multipartFile.getOriginalFilename();
        fileNames.add(originalFilename);
        String[] split = originalFilename.split("\\.");
        if (split != null && split.length > 1) {
            String suffix = split[split.length - 1];
            //获取文件名
            String convertFileName = System.currentTimeMillis() + getUUIDSixNum() + "." + suffix;
            File file = new File(new File(filePath).getAbsolutePath() + File.separator + "file-upload" + File.separator + UUID.randomUUID());
            //检测是否存在目录
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            multipartFile.transferTo(file);
            //设置放到数据库字段的值
            fileNames.add(convertFileName);

        } else {
            throw new WarnTitleException("upload-file-err-format");
        }
        return fileNames;
    }

    /**
     * 导入数据回滚操作
     */
    public void rollBackInstanceDataByImport(RollBackInstanceImportInfo param) throws Exception {
        InstanceImportHistoryServiceImpl importHistoryService = SpringUtils.getBean(InstanceImportHistoryServiceImpl.class);
        if (CollectionUtils.isNotEmpty(param.getIds())) {
            SearchParam searchParam = new SearchParam();
            //根据导入操作Id查询导入实例数据
            searchParam.addSubCondition(CMDBTool.getFieldName(InstanceImportResultInfo::getHistoryId)
                    , new SubCondition(CriteriaOpsType.in.name(), param.getIds()));
            List<InstanceImportResultInfo> exportResultList = importHistoryService.getExportResultList(searchParam);

            if (CollectionUtils.isNotEmpty(exportResultList)) {
                //导入详情数据中，获取实例Id
                Set<String> instanceIds = exportResultList.stream().filter(s -> !Strings.isNullOrEmpty(strValueConvert(s.getInstanceId()))).map(s -> s.getInstanceId()).collect(Collectors.toSet());
                //TODO 如果资产被自动化，topo等其他模块占用，是否强删除
                if (CollectionUtils.isNotEmpty(instanceIds)) {
                    InstanceServiceImpl instanceService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
                    //是否释放占用的实物标签Code
                    if (param.isReuseCodeFlag()) {
                        //释放，先将实物标签Code存入code缓存表中，在删除实例资产
                        //1:先查询资产
                        List<InstanceInfo> instanceInfoList = instanceService.doListByIdsNotAuth(new ArrayList<>(instanceIds));
                        if (CollectionUtils.isNotEmpty(instanceInfoList)) {
                            Set<String> collect = instanceInfoList.stream().filter(s -> s.getData() != null && !Strings.isNullOrEmpty(strValueConvert(s.getData().get(mwAssetCodingKey)))).map(s -> strValueConvert(s.getData().get(mwAssetCodingKey))).collect(Collectors.toSet());
                            instanceService.insertAssetsCodeCacheList(new ArrayList<>(collect));
                        } else {
                            //实例数据不存在
                            throw new WarnTitleException("instanceInfo-not-exist-error");
                        }
                    }
                    //删除资产
                    InstanceIdsParam deleteParams = new InstanceIdsParam();
                    deleteParams.setIds(new ArrayList<>(instanceIds));
                    instanceService.doBatchRemove(deleteParams);

                    // 更新同步记录已回滚
                    importHistoryService.updateRollBackFlag(param.getIds());
                } else {
                    throw new WarnTitleException("instanceId-not-exist-error");
                }
            } else {
                throw new WarnTitleException("no-find-data-error");
            }
        }
    }

}

